package com.lemurian.bankdata.action.base;

import java.sql.Timestamp;
import java.util.Date;
import java.util.List;

import org.apache.struts2.ServletActionContext;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;
import org.springframework.beans.factory.annotation.Autowired;

import com.lemurian.bankdata.dto.LogHelper;
import com.lemurian.bankdata.lite.authentication.BankDataPrincipal;
import com.lemurian.bankdata.lite.enums.UserActivityType;
import com.lemurian.bankdata.lite.logger.BankDataLogger;
import com.lemurian.bankdata.lite.struts.Pager;
import com.lemurian.bankdata.lite.struts.PartialList;
import com.lemurian.bankdata.lite.utils.GeneralConstant;
import com.lemurian.bankdata.lite.utils.GlobalFunction;
import com.lemurian.bankdata.services.ActivityLogService;
import com.lemurian.bankdata.services.ActivityTypesService;
import com.lemurian.bankdata.utils.BaseAction;
import com.lemurian.entity.ActivityTypes;
import com.lemurian.entity.User;
import com.opensymphony.xwork2.Preparable;

public class ActivityTypesAction extends BaseAction implements Preparable {

	private static final long serialVersionUID = 1L;
	
	private BankDataLogger log = BankDataLogger.getLogger(ActivityTypesAction.class.getSimpleName());

	private ActivityTypes activityType = new ActivityTypes();
	private List<ActivityTypes> activityTypes;
	
	private User user;
	private BankDataPrincipal principal;
	
	private int id = 0;
	
	@Autowired private ActivityTypesService activityTypesService;
	
	@Autowired 
	private ActivityLogService userActivityLogService;
	private LogHelper userActivityLog;
	
	@Override
	public void prepare() throws Exception {
		principal = (BankDataPrincipal) getSession().get(GeneralConstant.USER_PRINCIPAL);
		user = principal.getUser();
		
		if(id > 0) {
			activityType = (ActivityTypes) activityTypesService.findById(id);
		}
	}
	
	@Override
	public String list() {
		log.info("list Activity Types");

        setPreviousPage(GeneralConstant.LIST);
        
        log.sInfo(" :: Start     [%s] ", getStart());
        log.sInfo(" :: Count     [%s] ", getCount());
        log.sInfo(" :: Order By  [%s] ", getOrderBy());
        log.sInfo(" :: Asc Desc  [%s] ", getAscDesc());
        
        try {
            PartialList<ActivityTypes> partialList = activityTypesService.findByCriteria(getStart(), getCount(),
                    getAscDesc().equalsIgnoreCase("asc") ? Order.desc(getOrderBy().length() > 0 ? getOrderBy() : "id") : Order.asc(getOrderBy().length() > 0 ? getOrderBy() : "id"),
    				activityType.getDescription() != null && activityType.getDescription().length() > 0 ? Restrictions.ilike("description", activityType.getDescription(), MatchMode.ANYWHERE) : Restrictions.ne("id", new Integer(-1))
                    );
            
            activityTypes = partialList.getList();

            setPager(Pager.generatePager(getStart(), getCount(), partialList.getTotal()));
            setPagerItem(Pager.generatePagerItem(getStart(), getCount(), partialList.getTotal()));
            
            partialList = null;
            
        } catch (Exception e) {
            return INPUT;
        }
        setMappedRequest(GeneralConstant.LIST);
        return SUCCESS;
	}
	
	@Override
	public String add() {
		
		getSession().put(GeneralConstant.TIME_IN_SESSION, new Date());
		
		setPreviousPage(GeneralConstant.ADD);
		setMappedRequest(GeneralConstant.SAVE);
		return SUCCESS;
	}
	
	@Override
	public String save() {
		try {
			String message = "";
			if(id > 0) {
				message = "Update";
				activityType.setUpdateBy(user.getName());
				activityType.setUpdateDate(new Timestamp(System.currentTimeMillis()));
				
				userActivityLog = new LogHelper(user, UserActivityType.UPDATE_ACTIVITY_TYPES);
			} else {
				message = "Add";
				activityType.setCreateBy(user.getName());
				activityType.setCreateDate(new Timestamp(System.currentTimeMillis()));
				activityType.setSequence(activityTypesService.getLastSequence());
				
				userActivityLog = new LogHelper(user, UserActivityType.ADD_ACTIVITY_TYPES);
			}
			
			activityType.setDescription(activityType.getDescription().toUpperCase());
			activityTypesService.save(activityType);
			
			try {
                message += " " + activityType.getDescription() + " is success";
                addCustomActionMessage(message);
                
                log.sInfo(" :: User [%s:%s] is successfully save [%s:%s]", user.getId(), user.getName(), activityType.getId(), activityType.getDescription());
                userActivityLog.setStatus(LogHelper.SUCCESS_ACTIVITY);
            } catch (Exception e) {
                message += " " + activityType.getDescription() + " is failed, message : "+e.getMessage();
                addCustomActionMessage(message);
                log.sInfo(" :: Error was raised when User [%s:%s] save [%s:%s]", user.getId(), user.getName(), activityType.getId(), activityType.getDescription());
                
                //set activity log status into failed
                userActivityLog.setStatus(LogHelper.FAILED_ACTIVITY);
                userActivityLog.setErrorMsg(e.getMessage());
            }
            
            userActivityLog.setSessionId(ServletActionContext.getRequest().getSession().getId());
            userActivityLog.setStartDate((Date) getSession().get(GeneralConstant.TIME_IN_SESSION));
            userActivityLog.getAdditionalParams().add(activityType.getDescription());
            userActivityLogService.saveUserActivity(userActivityLog);
            getSession().remove(GeneralConstant.TIME_IN_SESSION);
			
		} catch (Throwable t) {
			t.printStackTrace();
		}
		
		setMappedRequestFullPath("/ActivityTypesAction_list.do");
		return GeneralConstant.REDIRECT;
	}

	@Override
	public String delete() {
		try {
			activityTypesService.delete(activityType);
			
			userActivityLog = new LogHelper(user, UserActivityType.DELETE_ACTIVITY_TYPES);
			
			String message = "";
            try {
                message = "Delete " + activityType.getDescription() + " is success";
                addCustomActionMessage(message);
                log.sInfo(" :: User [%s:%s] is successfully delete Activity Types [%s:%s]", user.getId(), user.getName(), activityType.getId(), activityType.getDescription());

                //check if activity is success
                userActivityLog.setStatus(LogHelper.SUCCESS_ACTIVITY);
            } catch (Exception e) {
                message = "Delete " + activityType.getDescription() + " is failed, message : "+e.getMessage();
                addCustomActionError(message);
                log.sInfo(" :: Error was raised when User [%s:%s] delete [%s:%s]", user.getId(), user.getName(), activityType.getId(), activityType.getDescription());
                
                //set activity log status into failed
                userActivityLog.setStatus(LogHelper.FAILED_ACTIVITY);
                userActivityLog.setErrorMsg(e.getMessage());
            }
            //save activity log
            userActivityLog.getAdditionalParams().add(activityType.getDescription());
            userActivityLogService.saveUserActivity(userActivityLog);
            
		} catch (Throwable t) {
			addCustomActionError(t.getMessage());
			log.info("Error delete activityType : " + t.getMessage());
			t.printStackTrace();
		}
		
		setMappedRequestFullPath("ActivityTypesAction_list.do");
		return GeneralConstant.REDIRECT;
	}

	@Override
	public String detail() {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public String edit() {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public String update() {
		// TODO Auto-generated method stub
		return null;
	}

	public ActivityTypes getActivityType() {
		return activityType;
	}

	public void setActivityType(ActivityTypes activityType) {
		this.activityType = activityType;
	}

	public List<ActivityTypes> getActivityTypes() {
		return activityTypes;
	}

	public void setActivityTypes(List<ActivityTypes> activityTypes) {
		this.activityTypes = activityTypes;
	}

	public int getId() {
		return id;
	}

	public void setId(String id) {
		int id_ = 0;
		if(id != null && !id.equalsIgnoreCase("0")) {
			id = GlobalFunction.decodeParameter(id);
	        id_ = Integer.parseInt(id);
		}
        this.id = id_;
	}
	
}
